package org.net5ijy.security.web.filter;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.net5ijy.security.config.security.SecurityConfig;
import org.net5ijy.security.validate.SmsValidateCodeGenerator;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * MobileAuthenticationFilter
 *
 * @author XGF
 * @date 2020/11/30 22:20
 */
public class MobileAuthenticationFilter extends
    AbstractAuthenticationProcessingFilter {

  private boolean postOnly = true;

  public MobileAuthenticationFilter() {
    super(new AntPathRequestMatcher(
        SecurityConfig.MOBILE_LOGIN_PROCESSING_URL, "POST"));
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request,
      HttpServletResponse response) throws AuthenticationException,
      IOException, ServletException {

    String method = request.getMethod();

    // 判断是不是post请求
    if (postOnly && !method.equalsIgnoreCase("POST")) {
      throw new AuthenticationServiceException(
          "Authentication method not supported: " + method);
    }

    // 从请求中获取手机号码
    String mobile = request
        .getParameter(SmsValidateCodeGenerator.MOBILE_PARAMETER_NAME);

    if (mobile == null) {
      mobile = "";
    }

    mobile = mobile.trim();

    // 创建MobileAuthenticationToken(未认证)
    MobileAuthenticationToken token = new MobileAuthenticationToken(mobile);

    setDetails(request, token);

    Authentication authentication = this.getAuthenticationManager().authenticate(token);

    // 返回Authentication实例
    // return provider.authenticate(token);
    return authentication;
  }

  protected void setDetails(HttpServletRequest request,
      MobileAuthenticationToken authRequest) {
    authRequest.setDetails(authenticationDetailsSource
        .buildDetails(request));
  }

  public void setPostOnly(boolean postOnly) {
    this.postOnly = postOnly;
  }
}
